package com.heima.service.impl;

import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.heima.domain.HhPatient;
import com.heima.dto.PatientDto;
import com.heima.mapper.HhPatientMapper;
import com.heima.service.IHhPatientService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.thread.CacheThread;
import com.heima.thread.UserThreadLocal;
import com.heima.vo.PatientVo;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 就诊人 服务实现类
 * </p>
 *
 * @author 黑马程序员
 * @since 2023-01-29
 */
@Service
public class HhPatientServiceImpl extends ServiceImpl<HhPatientMapper, HhPatient> implements IHhPatientService {
    @Autowired
    private HhPatientMapper hhPatientMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public List<PatientVo> patientList() {
        Integer userId = UserThreadLocal.getUserLocal();

        String cache = redisTemplate.opsForValue().get("patientList:user_" + userId);
        if (!StringUtils.isEmpty(cache)) {

            List<PatientVo> voList = JSON.parseArray(cache, PatientVo.class);
            return voList;
        }

        LambdaQueryWrapper<HhPatient> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(HhPatient::getUserId, userId);

        List<HhPatient> hhPatients = hhPatientMapper.selectList(wrapper);
        List<PatientVo> voList = new ArrayList<>();
        for (HhPatient hhPatient : hhPatients) {
            PatientVo vo = new PatientVo();
            BeanUtils.copyProperties(hhPatient, vo);
            String cardNumber = vo.getCardNumber();
            String cardNumber1 = DesensitizedUtil.idCardNum(cardNumber, 4, 4);
            vo.setCardNumber(cardNumber1);
            voList.add(vo);
        }
        // 把查到mysql的数据写到redis
        // CacheThread cacheThread=new CacheThread(redisTemplate,userId,voList);
        //   ThreadPoolExecutor pool=new ThreadPoolExecutor(8,
        //           10,
        //           1000,
        //           TimeUnit.SECONDS,
        //           new ArrayBlockingQueue<>(100),
        //            null,
        //           new ThreadPoolExecutor.AbortPolicy());
        //   pool.submit(cacheThread);
        redisTemplate.opsForValue().set("patientList:user_" + userId, JSON.toJSONString(voList));

        return voList;
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean removePatient(String patientId) {
        int res = hhPatientMapper.deleteById(patientId);
        Integer userId = UserThreadLocal.getUserLocal();
        // 移除redis数据
        redisTemplate.delete("patientList:user_" + userId);

        if (res == 0) {
            throw new RuntimeException("删除失败");
        }
        return true;
    }

    @Override
    public HhPatient getPatientByPatientId(String patientId) {
        HhPatient patient = hhPatientMapper.selectById(patientId);

        return patient;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void savePatient(PatientDto dto) {
        Integer userId = UserThreadLocal.getUserLocal();
        //判断就诊人数量是否大于等于5
        LambdaUpdateWrapper<HhPatient> wrapper=new LambdaUpdateWrapper<>();
        wrapper.eq(HhPatient::getUserId,userId);
        List<HhPatient> hhPatients = hhPatientMapper.selectList(wrapper);
        if (hhPatients.size()==5){
            throw new RuntimeException("就诊人数量过多，添加失败");
        }

        HhPatient hhPatient = new HhPatient();
        BeanUtils.copyProperties(dto, hhPatient);

        // 把其他默认就诊人设置为非默认
        if (dto.getIsDefault()) {
            HhPatient hhPatient1 = new HhPatient();
            hhPatient1.setIsDefault(0);
            LambdaUpdateWrapper<HhPatient> wrapper2 = new LambdaUpdateWrapper<>();
            wrapper2.eq(HhPatient::getUserId, userId);
            int update = hhPatientMapper.update(hhPatient1, wrapper2);
            if (update == 0) {
                throw new RuntimeException("添加失败");
            }
        }
        // todo
        hhPatient.setUserId(userId);

        int res = hhPatientMapper.insert(hhPatient);
        if (res != 1) {
            throw new RuntimeException("添加失败");
        }
        redisTemplate.delete("patientList:user_" + userId);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updatePatient(PatientDto dto, Integer patientId) {
        HhPatient hhPatient = new HhPatient();
        BeanUtils.copyProperties(dto, hhPatient);

        if (hhPatient == null) {
            throw new RuntimeException("就诊人不存在");
        }
        Integer userId = UserThreadLocal.getUserLocal();
        /*清空默认就诊人*/
        if (dto.getIsDefault()) {
            HhPatient hhPatient1 = new HhPatient();
            hhPatient1.setIsDefault(0);
            LambdaUpdateWrapper<HhPatient> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(HhPatient::getUserId, userId);
            int update = hhPatientMapper.update(hhPatient1, wrapper);
            if (update == 0) {
                throw new RuntimeException("添加失败");
            }

        }
        hhPatient.setIsDefault(1);
        LambdaUpdateWrapper<HhPatient> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(HhPatient::getId, patientId);
        wrapper.eq(HhPatient::getUserId, userId);
        hhPatientMapper.update(hhPatient, wrapper);
        redisTemplate.delete("patientList:user_" + userId);
    }
}
